Garbage collection, also commonly referred to as automatic memory management, attempts to automatically recycle dynamically allocated memory. Dynamically allocated memory is memory that is created at runtime and that is stored in an area of memory commonly referred to as the heap. There are several techniques that have been developed to perform garbage collection.
Each technique uses a collection strategy for determining when an object on the heap should best be recycled. Hereinafter, objects within the heap are referred to as managed objects. One collection strategy collects the managed objects based on the size (e.g., amount of memory) of the managed object. For example, this collection strategy may decide to clean up resources associated with a larger managed object earlier than a smaller managed object because collecting the larger managed object will free up more memory. Thus, by implementing a collection strategy that collects larger managed objects earlier than the smaller managed objects, the collection strategy minimizes the number of times the garbage collection process needs to run. This is beneficial because running the garbage collection process consumes resources and causes other programs to experience execution delays.
However, one problem with this collection strategy is that small managed objects may actually reference large amounts of unmanaged memory. Then, because the garbage collector bases its strategy on the size of the managed object, the garbage collector may wait to recycle these small managed objects until later. This is undesirable because each process is allowed a predetermined amount of total memory. The predetermined amount of total memory includes managed memory and unmanaged memory. Therefore, in order to efficiently manage its memory, the garbage collector may initiate a collection process more frequently on its larger objects with less success than if it had initiated the collection process on the smaller objects referencing large amounts of unmanaged memory.
In order to overcome this limitation, modules can directly invoke the garbage collection process on their own objects. Thus, by directly invoking the garbage collection process on its own small objects that reference large amounts of unmanaged memory, the garbage collection process can force the de-allocation of the unmanaged memory when it destroys the small objects. While this successfully overcomes the problem and recycles the smaller objects that may not have been automatically chosen for recycling, it is potentially very inefficient. For example, a module may consider that the allocation of one mega-byte of memory is a large amount and may directly invoke the garbage collector to recycle the object right away. However, the garbage collector may view this one megabyte allocation as inconsequential given a heap size of 1 Gbytes. These inefficiencies multiply when multiple modules each directly invoke the garbage collector. When this occurs, the garbage collection process may consume a large percentage of the computing resources and cause undesirable delays to other executing processes.
Thus, until now, there has not been a satisfactory solution for performing garbage collection when large allocations of unmanaged memory exist.